import { Http, Response } from '@angular/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map'
import 'rxjs/add/operator/catch'

/*
  Generated class for the RestProvider provider.

  See https://angular.io/guide/dependency-injection for more info on providers
  and Angular DI.
*/
@Injectable()
export class RestProvider {

  constructor(public http: Http) {
  }

  //feed
  private apiUrlFeeds = 'https://imoocqa.gugujiankong.com/api/feeds/get';

  //account
  private apiUrlRegister = 'https://imoocqa.gugujiankong.com/api/account/register';
  private apiUrlLogin = 'https://imoocqa.gugujiankong.com/api/account/login';
  private apiUrlLoginWithMd5 = 'https://imoocqa.gugujiankong.com/api/account/loginwithmd5';
  private apiUrlUserInfo = 'https://imoocqa.gugujiankong.com/api/account/userinfo';
  private apiUrlUpdateNickName = 'https://imoocqa.gugujiankong.com/api/account/updatenickname';

  private apiGetUserQuestionList = "https://imoocqa.gugujiankong.com/api/account/getuserquestionlist";

  //question
  private apiUrlQuestionSave = 'https://imoocqa.gugujiankong.com/api/question/save';
  private apiUrlQuestionList = 'https://imoocqa.gugujiankong.com/api/question/list?index=1&number=10';
  private apiUrlGetQuestion = "https://imoocqa.gugujiankong.com/api/question/get";
  private apiUrlAnswer = "https://imoocqa.gugujiankong.com/api/question/answer";
  private apiUrlSaveFavourite = "https://imoocqa.gugujiankong.com/api/question/savefavourite";
  private apiUrlUserNotifications = "https://imoocqa.gugujiankong.com/api/account/usernotifications";

  login(mobile, password): Observable<string[]> {
    let url = `${this.apiUrlLogin}?mobile=${mobile}&password=${password}`
    return this.getUtlReturn(url)
  }

  /**
   *获取问题的详情 
   * 
   * @param {any} id 
   * @returns {Observable<string[]>} 
   * @memberof RestProvider
   */
  getQuestion(id): Observable<string[]> { 
    let url = `${this.apiUrlGetQuestion}?id=${id}`
    return this.getUtlReturn(url)
  }

  /**
   * 获取用户的提醒消息
   * 
   * @param {any} userId 
   * @param {any} type question/answer/favourite
   * @returns {Observable<string[]>} 
   * @memberof RestProvider
   */
  getUserNotifications(userId): Observable<string[]> {
    let url = `${this.apiUrlUserNotifications}?userid=${userId}`
    return this.getUtlReturn(url)
  }

  /**
   * 获取所有的新问题
   * 
   * @param {any} userId 
   * @returns {Observable<string[]>} 
   * @memberof RestProvider
   */
  getUserQuestionList(userId, type): Observable<string[]> {
    let url = `${this.apiGetUserQuestionList}?userid=${userId}&type=${type}`
    return this.getUtlReturn(url)
  }
  /**
   * 获取问题的详情，传递userid获取到当前用户有没有关注此问题
   * 
   * @param {any} questionId 
   * @param {any} userId 
   * @returns {Observable<string[]>} 
   * @memberof RestProvider
   */
  getQuestionwithUser(questionId, userId): Observable<string[]> {
    let url = `${this.apiUrlGetQuestion}?id=${questionId}&userid=${userId}`
    return this.getUtlReturn(url) 
  }

  saveFavourite(questionId,userId): Observable<string[]> { 
    let url = `${this.apiUrlSaveFavourite}?id=${questionId}&userid=${userId}`
    return this.getUtlReturn(url) 
  }

  answer(userId, questionId, content): Observable<string[]> {
    let url = this.apiUrlAnswer + "?userid=" + userId + "&questionid=" + questionId + "&content=" + content
    return this.getUtlReturn(url)
  }
  /**
   * 注册请求
   * ionic课程安全性不高，安全性方面需要做详细的设计和处理
   * 密码的传递应该在传递参数之前进行加密，并且服务器端也应该进项相应的处理
   * 
   * @param {any} mobile 
   * @param {any} nickname 
   * @param {any} password 
   * @returns {Observable<string[]>} 
   * @memberof RestProvider
   */
  register(mobile,nickname, password): Observable<string[]> {
    let url = `${this.apiUrlRegister}?mobile=${mobile}&nickname=${nickname}&password=${password}`
    return this.getUtlReturn(url)
  }

  /**
   * 请求首页的feeds
   * 
   * @returns {Observable<string[]>} 
   * @memberof RestProvider
   */
  getFeeds(): Observable<string[]> {
    return this.getUtlReturn(this.apiUrlFeeds)
  }

  getQuestions(): Observable<string[]> {
    return this.getUtlReturn(this.apiUrlQuestionList)
  }
  /**
   * 获取用户信息
   * 
   * @param {any} userId 
   * @returns {Observable<string[]>} 
   * @memberof RestProvider
   */
  getUserInfo(userId):Observable<string[]> {
    let url = `${this.apiUrlUserInfo}?userid=${userId}`
    return this.getUtlReturn(url)
  }

  /**
   * 更新昵称
   * 
   * @param {any} userId 
   * @param {any} nickname 
   * @returns {Observable<string[]>} 
   * @memberof RestProvider
   */
  updateNickName(userId, nickname): Observable<string[]>{
    let url = `${this.apiUrlUpdateNickName}?userid=${userId}&nickname=${nickname}`
    return this.getUtlReturn(url)
  }

  /**
   * 保存提问
   * 
   * @param {any} userId 
   * @param {any} title 
   * @param {any} content 
   * @returns {Observable<string[]>} 
   * @memberof RestProvider
   */
  saveQuestion(userId, title, content): Observable<string[]> {
    let url = `${this.apiUrlQuestionSave}?userid=${userId}&title=${title}&content=${content}`
    return this.getUtlReturn(url)
  }

  /**
   * 全局获取HTTP请求的方法
   * 
   * @private
   * @param {string} url 
   * @returns {Observable<string[]>} 
   * @memberof RestProvider
   */
  private getUtlReturn(url: string): Observable<string[]> {
    return this.http.get(url)
                    .map(this.extractData)
                    .catch(this.handleError)
  }

  /**
   * 处理接口返回的数据，处理成json
   * 
   * @private
   * @param {Response} res 
   * @returns 
   * @memberof RestProvider
   */
  private extractData(res: Response) {
    let body = res.json()
    return JSON.parse(body) || ''
  }

  /**
   * 处理请求中的错误
   * 
   * @private
   * @param {(Response | any)} error 
   * @returns 
   * @memberof RestProvider
   */
  private handleError(error: Response | any) {
    let errMsg: string
    if( error instanceof Response) {
      const body = error.json() || ''
      const err = body.error || JSON.stringify(body)
      errMsg = `${error.status} - ${error.statusText || ''} ${err}`
    } else {
      errMsg = error.message ? error.message : error.toString()
    }

    console.error(errMsg)
    return Observable.throw(errMsg)
  }
}
